package com.wsm.common.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.wsm.common.enums.DataSourceName;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MybatisPlusConfig {
	/**
	 * 获取数据库配置信息
	 * 修改时需要修改ConfigurationProperties中内容
	 *
	 * @return
	 */
	@Bean(value = "first_dataSource")   //声明其为Bean实例
	@Primary  //在同样的DataSource中，首先使用被标注的DataSource
	@ConfigurationProperties("spring.datasource.first")
	public DataSource first_dataSource() {
		return new DruidDataSource();
	}

	@Bean("second_dataSource")   //声明其为Bean实例
	@ConfigurationProperties("spring.datasource.second")
	public DataSource second_dataSource() {
		return new DruidDataSource();
	}

	/**
	 * 动态数据源配置
	 *
	 * @return
	 */
	@Bean
	@Primary
	public DataSource multipleDataSource(@Qualifier("first_dataSource") DataSource first_dataSource,
										 @Qualifier("second_dataSource") DataSource second_dataSource) {
		Map<Object, Object> targetDataSources = new HashMap<>(2);
		targetDataSources.put(DataSourceName.First.getName(), first_dataSource);
		targetDataSources.put(DataSourceName.Second.getName(), second_dataSource);
		DynamicDataSource multipleDataSource = new DynamicDataSource(first_dataSource, targetDataSources);
		return multipleDataSource;
	}

	/**
	 * @return
	 * @throws IOException
	 */
	@Bean("sqlSessionFactory")
	public MybatisSqlSessionFactoryBean sqlSessionFactory() throws Exception {
		MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
		sqlSessionFactory.setDataSource(multipleDataSource(first_dataSource(), second_dataSource()));
		MybatisConfiguration configuration = new MybatisConfiguration();
		configuration.setJdbcTypeForNull(JdbcType.NULL);
		configuration.setMapUnderscoreToCamelCase(true);
		configuration.setLogImpl(StdOutImpl.class);
		configuration.setCacheEnabled(false);
		sqlSessionFactory.setConfiguration(configuration);
		sqlSessionFactory.setGlobalConfig(new GlobalConfig().setMetaObjectHandler(metaObjectHandler()));
		sqlSessionFactory.setPlugins(new Interceptor[]{paginationInterceptor()});
		sqlSessionFactory.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources
						("classpath*:mybatis/**/*Mapper.xml"));
		return sqlSessionFactory;
	}

	@Bean(name = "dataSourceTransactionManager")
	public DataSourceTransactionManager dataSourceTransactionManager(DynamicDataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	@Bean(name = "sqlSessionTemplate")
	public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	/**
	 * mybatis-plus分页插件
	 */
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor page = new PaginationInterceptor();
		page.setDialectType("mysql");
		return page;
	}

	@Bean
	public MetaObjectHandler metaObjectHandler() {
		return new MyMetaObjectHandler();
	}
}
